/**
 * 
 */
package simulation;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

/**
 * @author aclayton
 *
 */
public class Map {
	private Rect boundingbox;
	private double width, length;
	private ArrayList<Obstacle> obstacles;	
	
	public Map(double width, double length){
		boundingbox = new Rect(0, length, width, 0);
		this.width = width;
		this.length = length;
		obstacles = new ArrayList<Obstacle>();
	}
	
	public Map(Rect boundingbox){
		this.boundingbox = boundingbox;
		this.width = boundingbox.getHeight();
		this.length =  boundingbox.getWidth();
		obstacles = new ArrayList<Obstacle>();
	}
	
	public Rect getBoundingBox(){
		return boundingbox;
	}
	
	public double getWidth(){
		return width;
	}
	
	public double getLength(){
		return length;
	}
	
	public void addObstacle(Obstacle obs){
		obstacles.add(obs);
	}
	
	public void addObstacles(ArrayList<Obstacle> obs){
		obstacles.addAll(obs);
	}
	

	
	public ArrayList<Obstacle> getObstacles(){
		return obstacles;
	}

	
	public String toString(){
		String str = "Map("+width+","+length+")";
		return str;
	}
	
	public void generateRandomObstacles(int numObs){
		for(int a = 0; a < numObs; a++)
			obstacles.add(Obstacle.createRandomObstacleInBox(0, width, length, 0));
	}
	
	public void saveToFile(String filename){
		try{
			PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
			out.println("Width="+width);
			out.println("Length="+length);
			
			for(Obstacle ob : obstacles)
				out.println(ob);
			
			out.close();
		} catch(Exception e){}
	}
	
	public void loadFromFile(String fromFile) throws FileNotFoundException{
		Scanner sc = new Scanner(new File(fromFile));
		String temp;
		String[] strs;
		char tempchar;
		try{
			while(sc.hasNextLine()){
				temp = sc.nextLine();
				//System.out.println(temp);
				tempchar = temp.charAt(0);
				//System.out.println(tempchar);
				switch(tempchar){
				case 'W':
					strs = temp.split("=");
					width = Double.parseDouble(strs[1]);
					break;
				case 'L':
					strs = temp.split("=");
					length = Double.parseDouble(strs[1]);
					break;
				case 'O':
					obstacles.add(Obstacle.createFromString(temp));
					break;
				}
			}
		} 
		finally {
			sc.close();
		}
		
		boundingbox = new Rect(0,length, width, 0);
	}
	
	public Map getSubMap(Rect box){
		Map subMap = new Map(box);
		
		for(Obstacle ob : obstacles){
			ArrayList<Point> pts = ob.getPoints();
			ArrayList<LineSeg> segs = ob.getSegments();
			
			boolean allOut = true;
			for(Point p : pts){
				if(box.pointInBox(p))
					allOut = false;
			}
			
			if(!allOut)
				subMap.addObstacle(ob);
		}
		
		return subMap;
	}

	public ArrayList<Map> splitIntoSubmaps(int numSubMaps) {
		double newLength = length/numSubMaps;
		
		ArrayList<Map> submaps = new ArrayList<Map>();
		
		for(int i =0 ; i < numSubMaps; i++)
			submaps.add(getSubMap(new Rect(i*newLength, (i+1)*newLength, width, 0)));
		
		return submaps;
		
	}
	
	public HashSet<Rect> splitIntoBoundingBox(int numBoxes){
		HashSet<Rect> set = new HashSet<Rect>();
		double newLength = length/numBoxes;
		
		for(int i =0 ; i < numBoxes; i++)
			set.add(new Rect(i*newLength, (i+1)*newLength, width, 0));
		
		return set;
	}
	
}
